/**
 * 项目版本列表获取接口测试用例
 *
 * Created by snowingsea on 2020/02/09.
 */
const chai = require('chai');
const should = chai.should(); // eslint-disable-line no-unused-vars
chai.use(require('chai-http'));

const common = require('./../../common');
const Administrator = require('./../../../models/administrator');
const uri = require('./../uri');
const { statusKind } = require('./../../../../phoenix/models/project-versions');

module.exports = describe('/GET projects/:id/versions.json', function () {
  const administrator = new Administrator();
  let project;
  const versionCount = 13;
  const newUserIds = [];
  function url(projectId) {
    if (!projectId) {
      projectId = project.projectId;
    }
    return `/projects/${projectId}/versions.json`;
  }
  function getTester() {
    return project.creator;
  }

  before(function (done) {
    administrator.login()
      .then(() => administrator.createRandomTester())
      .then((tester) => {
        newUserIds.push(tester.userId);
        return tester.createRandomProjects(2);
      })
      .then((projects) => {
        [project] = projects;
        return projects[1].createRandomVersions(2);
      })
      .then(() => project.createRandomVersions(versionCount))
      .then((versions) => project.randomFreezeVersions(versions))
      .then(() => administrator.createRandomTester())
      .then((newTester) => {
        newUserIds.push(newTester.userId);
        return newTester.createRandomProjects(2);
      })
      .then(([project]) => project.createRandomVersions(3))
      .then(() => {
        done();
      })
      .catch(done);
  });
  after(function (done) {
    administrator.removeUsers(newUserIds)
      .then(() => {
        done();
      })
      .catch(done);
  });

  common.should.be.user(uri, url, 'get');
  common.should.be.tester(uri, url, 'get');
  const sortByKeys = ['versionId', 'versionName', 'createAt', 'visitAt', 'status'];
  common.should.complete.filter(uri, url, 'get', getTester, sortByKeys);

  // 正常获取项目版本列表
  it('it should GET project versions', function (done) {
    project.creator.login()
      .then(() => {
        chai.request(uri)
          .get(url())
          .set('Authorization', `Bearer ${project.creator.token.accessToken}`)
          .end((err, res) => {
            res.should.have.status(200);
            common.should.be.projectVersionsMessage(res.body);
            res.body.pagination.total.should.be.eql(versionCount + 1);
            done();
          });
      })
      .catch(done);
  });

  // 搜索
  it('it should search the project version by keyword', function (done) {
    let newVersion;
    project.createRandomVersion()
      .then((res) => {
        newVersion = res;
        return project.creator.login();
      })
      .then(() => {
        chai.request(uri)
          .get(url())
          .query({ q: newVersion.versionName })
          .set('Authorization', `Bearer ${project.creator.token.accessToken}`)
          .end((err, res) => {
            res.should.have.status(200);
            common.should.be.projectVersionsMessage(res.body);
            res.body.pagination.total.should.be.eql(1);
            res.body.versions[0].versionName.should.be.eql(newVersion.versionName);
            done();
          });
      })
      .catch(done);
  });

  // 筛选
  const filters = [
    { status: statusKind.normal },
    { status: statusKind.frozen },
  ];
  filters.forEach((filter) => {
    it(`it should get project versions with ${JSON.stringify(filter)}`, function (done) {
      project.creator.login()
        .then(() => {
          chai.request(uri)
            .get(url())
            .query(filter)
            .set('Authorization', `Bearer ${project.creator.token.accessToken}`)
            .end((err, res) => {
              res.should.have.status(200);
              common.should.be.projectVersionsMessage(res.body);
              res.body.versions.forEach((version) => {
                Object.keys(filter).forEach((key) => {
                  version[key].should.be.eql(filter[key]);
                });
              });
              done();
            });
        })
        .catch(done);
    });
  });

  // 项目访问后访问时间排序变动
  it('it should change when one of version is visited', function (done) {
    project.creator.login()
      .then(() => {
        const query = { sortBy: 'visitAt', order: 'desc' };
        chai.request(uri)
          .get(url())
          .query(query)
          .set('Authorization', `Bearer ${project.creator.token.accessToken}`)
          .end((err, res) => {
            res.should.have.status(200);
            common.should.be.projectVersionsMessage(res.body);
            const lastVersion = res.body.versions[res.body.versions.length - 1];
            project.getVersion(lastVersion.versionId)
              .then(() => {
                chai.request(uri)
                  .get(url())
                  .query(query)
                  .set('Authorization', `Bearer ${project.creator.token.accessToken}`)
                  .end((err, res) => {
                    res.should.have.status(200);
                    common.should.be.projectVersionsMessage(res.body);
                    res.body.versions[0].versionId.should.be.eql(lastVersion.versionId);
                    res.body.versions[0].visitAt.should.not.be.eql(lastVersion.visitAt);
                    done();
                  });
              })
              .catch(done);
          });
      })
      .catch(done);
  });

  // 新添加的项目应当在按访问排序第一位
  it('it should be first of versions sort by "visitAt" when add a new project version', function (done) {
    let firstVersionId;
    project.createRandomVersion()
      .then(({ versionId }) => {
        firstVersionId = versionId;
        return project.creator.login();
      })
      .then(() => {
        chai.request(uri)
          .get(url())
          .query({ sortBy: 'visitAt', order: 'desc' })
          .set('Authorization', `Bearer ${project.creator.token.accessToken}`)
          .end((err, res) => {
            res.should.have.status(200);
            common.should.be.projectVersionsMessage(res.body);
            res.body.versions[0].versionId.should.be.eql(firstVersionId);
            done();
          });
      })
      .catch(done);
  });
});
